package xyz.xtt.asset.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.hutool.json.JSONUtil;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.client.request.MintRequest;
import xyz.xtt.asset.client.request.TransferActionRequest;
import xyz.xtt.asset.client.request.TransferFromRequest;
import xyz.xtt.asset.client.response.AssetInfo;
import xyz.xtt.asset.client.response.BurnResponse;
import xyz.xtt.asset.client.response.MintResponse;
import xyz.xtt.asset.client.response.MyNftPage;
import xyz.xtt.asset.client.response.TransferActionResponse;
import xyz.xtt.asset.client.response.TransferFromResponse;
import xyz.xtt.asset.constants.ErrorMessage;
import xyz.xtt.asset.enums.OrderTypeEnum;
import xyz.xtt.asset.request.AssetTransferFromRequest;
import xyz.xtt.asset.request.BatchTransferFromRequest;
import xyz.xtt.asset.request.BurnRequest;
import xyz.xtt.asset.response.TransactionResponse;
import xyz.xtt.asset.service.INftService;
import xyz.xtt.asset.service.ITblAssetTransactionService;
import xyz.xtt.asset.vo.CreateGorupResult;
import xyz.xtt.asset.vo.CreateGroupRequest;
import xyz.xtt.common.asset.AssertUtils;
import xyz.xtt.common.response.ApiResult;

/**
 * 核心功能接口
 * 
 * @author huqibo
 * @date 2024/12/24
 */

@Slf4j
@RestController
@RequestMapping("/api/asset/nft")
public class NftController {
	@Autowired
	private ITblAssetTransactionService iTblAssetTransactionService;
	@Autowired
	private INftService nftService;

	@Operation(summary = "铸造")
	@PostMapping("/mint")
	public ApiResult<MintResponse> mint(@RequestBody @Valid MintRequest mintRequest) {
		log.info("/api/asset/nft/mint param:{}", JSONUtil.toJsonStr(mintRequest));
		MintResponse mint = nftService.mint(mintRequest, OrderTypeEnum.MINT);
		AssertUtils.isNull(mint, ErrorMessage.UNKNOWN_ERROR);
		return ApiResult.ok(mint);
	}

	@Operation(summary = "资产创建不上链")
	@PostMapping("/create")
	public ApiResult<MintResponse> create(@RequestBody @Valid MintRequest mintRequest) {
		log.info("/api/asset/nft/create param:{}", JSONUtil.toJsonStr(mintRequest));
		MintResponse mint = nftService.create(mintRequest);
		AssertUtils.isNull(mint, ErrorMessage.UNKNOWN_ERROR);
		return ApiResult.ok(mint);
	}

	@Operation(summary = "转移")
	@PostMapping("/transferFrom")
	public ApiResult<TransferFromResponse> transferFrom(@RequestHeader("platform") String platform,
			@RequestBody @Valid TransferFromRequest transferFromRequest) {
		log.info("/api/asset/nft/transferFrom platform:{}, param:{}", platform, JSONUtil.toJsonStr(transferFromRequest));
		TransferFromResponse transferFrom = nftService.transferFrom(platform, transferFromRequest);
		AssertUtils.isNull(transferFrom, ErrorMessage.UNKNOWN_ERROR);
		return ApiResult.ok(transferFrom);
	}

	@Operation(summary = "批量铸造")
	@PostMapping("/batchMint")
	public ApiResult<Boolean> batchMint(@RequestHeader("uid") String uid, @RequestBody @Valid List<MintRequest> mintRequest) {
		Boolean mint = nftService.batchMint(mintRequest);
		return ApiResult.ok(mint);
	}

	@Operation(summary = "批量转移")
	@PostMapping("/batchTransferFrom")
	public ApiResult<Boolean> batchTransferFrom(@RequestHeader("uid") String uid, @RequestBody @Valid BatchTransferFromRequest batchTransferFromRequest) {
		Boolean batchTransferFrom = nftService.batchTransferFrom(uid, batchTransferFromRequest);
		return ApiResult.ok(batchTransferFrom);
	}

	@Operation(summary = "打包转移")
	@PostMapping("/packageTransferFrom")
	public ApiResult<Boolean> packageTransferFrom(@RequestHeader("uid") String uid, @RequestBody @Valid List<TransferFromRequest> transferFromRequestList) {
		Boolean packageTransferFrom = nftService.packageTransferFrom(uid, transferFromRequestList);
		return ApiResult.ok(packageTransferFrom);
	}

	@Operation(summary = "销毁")
	@PostMapping("/burn")
	public ApiResult<BurnResponse> burn(@RequestHeader("platform") String platform, @RequestBody @Valid BurnRequest burnRequest) {
		log.info("/api/asset/nft/burn param:{}", JSONUtil.toJsonStr(burnRequest));
		BurnResponse burn = nftService.burn(platform, burnRequest);
		return ApiResult.ok(burn);
	}

	@Operation(summary = "资产详情")
	@GetMapping("/info")
	public ApiResult<AssetInfo> query(@RequestHeader("platform") String platform, String bizId, Long ownerId,
			@RequestParam(value = "needAttributes", defaultValue = "false") Boolean needAttributes) {
		log.info("/api/asset/nft/info platform:{},bizId:{},needAttributes:{}", platform, bizId, needAttributes);
		AssetInfo assetInfo = nftService.assetInfo(platform, bizId, ownerId, needAttributes);
		return ApiResult.ok(assetInfo);
	}

	@Operation(summary = "资产交易记录查询")
	@GetMapping("/transaction")
	public ApiResult<List<TransactionResponse>> transaction(@RequestHeader("uid") String uid, String type,
			@RequestParam(value = "currPage", defaultValue = "0") Integer currPage, @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
		List<TransactionResponse> transaction = iTblAssetTransactionService.transaction(uid, type, currPage, pageSize);
		return ApiResult.ok(transaction);
	}

	@Operation(summary = "帐户资产划转")
	@PostMapping("/account/transferFrom")
	public ApiResult<Boolean> accountTransferFrom(@RequestHeader("uid") String uid, @RequestBody @Valid AssetTransferFromRequest assetTransferFromRequest) {
		Boolean transferFrom = nftService.accountTransferFrom(assetTransferFromRequest);
		return ApiResult.ok(transferFrom);
	}

	@Operation(summary = "转移动作")
	@PostMapping("/transferAction")
	public ApiResult<TransferActionResponse> transferAction(@RequestHeader("platform") String platform,
			@RequestBody @Valid TransferActionRequest transferActionRequest) {
		log.info("/api/asset/nft/transferAction platform:{},param:{}", platform, JSONUtil.toJsonStr(transferActionRequest));
		TransferActionResponse transferAction = nftService.transferAction(transferActionRequest);
		AssertUtils.isNull(transferAction, ErrorMessage.UNKNOWN_ERROR);
		return ApiResult.ok(transferAction);
	}

	@Operation(summary = "我的资产列表")
	@GetMapping("/list")
	public ApiResult<MyNftPage> list(@RequestHeader("platform") String platform, String uid,
			@RequestParam(value = "filterZero", defaultValue = "false") Boolean filterZero,
			@RequestParam(value = "filterAssetType", defaultValue = "false") String filterAssetType,
			@RequestParam(value = "needAttributes", defaultValue = "false") Boolean needAttributes,
			@RequestParam(value = "currPage", defaultValue = "1") Integer currPage, @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
		log
				.info("/api/asset/nft/list platform:{},filterZero:{},filterAssetType:{},currPage:{},pageSize:{}", platform, filterZero, filterAssetType, currPage, pageSize);
		MyNftPage myNftPage = nftService.list(platform, uid, filterZero, needAttributes, filterAssetType, currPage, pageSize);
		return ApiResult.ok(myNftPage);
	}


	@Operation(summary = "创建群聊")
	@PostMapping("/group/create")
	public ApiResult<CreateGorupResult> createGroup(@RequestBody @Valid CreateGroupRequest createGroupRequest) {
		log.info("/api/asset/nft/group/create,param:{}", JSONUtil.toJsonStr(createGroupRequest));
		CreateGorupResult createGorup = nftService.createGorup(createGroupRequest);
		return  ApiResult.ok(createGorup);
	}
}
